package online.heycm.codegenerator.common.session;

import lombok.extern.slf4j.Slf4j;
import online.heycm.codegenerator.common.jdbc.Jdbc;
import online.heycm.platform.common.entity.exception.Assert;
import online.heycm.platform.common.tools.file.FileUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author hey
 * @version 1.0
 * @date 2023/12/21 10:14
 */
@Slf4j
public class SessionStorage {

    private static final Map<String, Session> SESSION = new ConcurrentHashMap<>();
    private static final int MAX_SIZE = 200;
    private static final int ALIVE = 1000 * 60 * 10;
    private static final int MAX_ALIVE = 1000 * 60 * 60;


    public static void put(Session session) {
        Assert.notNull(session, "Session不能是null");
        SESSION.put(session.getToken(), session);
    }

    public static Session get(String token) {
        return SESSION.get(token);
    }

    public static void close(String token) {
        Session session = get(token);
        if (session == null) {
            return;
        }
        close(session);
    }

    public static void close(Session session) {
        if (session == null) {
            return;
        }
        releaseResources(session);
        SESSION.remove(session.getToken());
    }

    private static void releaseResources(Session session) {
        Jdbc.close(session.getConnection());
        FileUtil.delete(session.getOutput());
    }

    public static boolean isFullStorage() {
        boolean full = SESSION.size() >= MAX_SIZE;
        if (full) {
            return true;
        }
        synchronized (SESSION) {
            return SESSION.size() >= MAX_SIZE;
        }
    }

    public static void destroy() {
        for (Map.Entry<String, Session> entry : SESSION.entrySet()) {
            releaseResources(entry.getValue());
        }
        SESSION.clear();
    }

    public static int clearTask(long currMillis) {
        log.info("清理前Session数量: {}", SESSION.size());
        List<String> keys = new ArrayList<>();
        for (Map.Entry<String, Session> entry : SESSION.entrySet()) {
            Session session = entry.getValue();
            if (currMillis - session.getOperateAt() > ALIVE || currMillis - session.getCreatedAt() > MAX_ALIVE) {
                releaseResources(session);
                keys.add(session.getToken());
                log.debug("清除Session: {}", session.getToken());
            }
        }
        keys.forEach(SESSION::remove);
        log.info("清理后Session数量: {}", SESSION.size());
        return keys.size();
    }
}
